/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package br.unesp.demac.bcc.soo.dao;

import br.unesp.demac.bcc.soo.bean.Contato;
import br.unesp.demac.bcc.soo.bean.Endereco;
import br.unesp.demac.bcc.soo.bean.Funcionario;
import br.unesp.demac.bcc.soo.bean.Login;
import br.unesp.demac.bcc.soo.util.FabricaConexao;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;

/**
 *
 * @author flavioam
 */
public class FuncionarioDAOImp implements FuncionarioDAO {

    @Override
    public boolean salvaFuncionario(Funcionario f) throws Exception {

        boolean saved = false;
        Connection con = null;

        try {

            con = FabricaConexao.getConexao();
            con.setAutoCommit(false);

            String sqlPessoa = "insert into Pessoas (nome,cpf) values (?,?)";

            PreparedStatement pstmtPessoa = con.prepareStatement(sqlPessoa, Statement.RETURN_GENERATED_KEYS);

            pstmtPessoa.setString(1, f.getNome());
            pstmtPessoa.setString(2, f.getCpf());

            pstmtPessoa.executeUpdate();

            ResultSet keys = pstmtPessoa.getGeneratedKeys();
            keys.next();
            int idPessoa = keys.getInt(1);
            f.setIdPessoa(idPessoa);

            String sqlFunc = "insert into Funcionarios (perfil, Pessoas_idPessoas) values (?,?)";

            PreparedStatement pstmtFunc = con.prepareStatement(sqlFunc);

            pstmtFunc.setString(1, f.getPerfil());
            pstmtFunc.setInt(2, idPessoa);

            pstmtFunc.executeUpdate();

            ContatoDAO contatoDAO = new ContatoDAOImp();
            contatoDAO.salvaContato(f, con);


            EnderecoDAO endDAO = new EnderecoDAOImp();
            endDAO.salvaEndereco(f, con);

            LoginDAO loginDAO = new LoginDAOImp();
            loginDAO.salvaLogin(f, con);

            con.commit();

            saved = true;

        } catch (SQLException e) {

            throw new Exception("Erro ao salvar funcionário: " + e.getMessage());

        } finally {
            FabricaConexao.fechar(con);
        }
        return saved;
    }

    @Override
    public ArrayList<Funcionario> selecionaTodosFuncionarios() throws Exception {

        ArrayList<Funcionario> l = new ArrayList<Funcionario>();
        Connection con = null;

        try {

            con = FabricaConexao.getConexao();

            String sql = "  select * from Pessoas as pes "
                    + "  inner join Funcionarios as func on(pes.idPessoas = func.Pessoas_idPessoas)"
                    + "  where pes.idPessoas in (select Pessoas_idPessoas from Funcionarios)";

            PreparedStatement pstmt = con.prepareStatement(sql);

            ResultSet rs = pstmt.executeQuery();

            while (rs.next()) {

                Funcionario f = new Funcionario();
                f.setNome(rs.getString("nome"));
                f.setCpf(rs.getString("cpf"));
                f.setIdPessoa(rs.getInt("idPessoas"));
                f.setPerfil(rs.getString("perfil"));

                LoginDAO lDao = new LoginDAOImp();
                Login login = lDao.selecionaLoginByIdPessoa(f.getIdPessoa());
                f.setLogin(login);

                EnderecoDAO eDao = new EnderecoDAOImp();
                Endereco end = eDao.selecionaEnderecoByIdPessoa(f.getIdPessoa());
                f.setEndereco(end);

                ContatoDAO cDao = new ContatoDAOImp();
                Contato cont = cDao.selecionaContadoByIdPessoa(f.getIdPessoa());
                f.setContato(cont);

                l.add(f);

            }

        } catch (SQLException e) {

            throw new Exception("Erro ao selecionar funcionários: " + e.getMessage());

        } finally {
            FabricaConexao.fechar(con);
        }
        return l;
    }

    @Override
    public Funcionario selecionaFuncionarioPorId(int id) throws Exception {

        Funcionario fRet = null;
        Connection con = null;

        try {

            con = FabricaConexao.getConexao();

            String sql = "  select * from Pessoas as pes "
                    + "  inner join Funcionarios as func on(pes.idPessoas = func.Pessoas_idPessoas)"
                    + "  where pes.idPessoas = ?";

            PreparedStatement pstmt = con.prepareStatement(sql);

            pstmt.setString(1, Integer.toString(id));

            ResultSet rs = pstmt.executeQuery();

            while (rs.next()) {

                Funcionario f = new Funcionario();
                f.setNome(rs.getString("nome"));
                f.setCpf(rs.getString("cpf"));
                f.setIdPessoa(rs.getInt("idPessoas"));
                f.setPerfil(rs.getString("perfil"));

                LoginDAO lDao = new LoginDAOImp();
                Login login = lDao.selecionaLoginByIdPessoa(f.getIdPessoa());
                f.setLogin(login);

                EnderecoDAO eDao = new EnderecoDAOImp();
                Endereco end = eDao.selecionaEnderecoByIdPessoa(f.getIdPessoa());
                f.setEndereco(end);

                ContatoDAO cDao = new ContatoDAOImp();
                Contato cont = cDao.selecionaContadoByIdPessoa(f.getIdPessoa());
                f.setContato(cont);

                fRet = f;

            }

        } catch (SQLException e) {

            throw new Exception("Erro ao selecionar funcionários: " + e.getMessage());

        } finally {
            FabricaConexao.fechar(con);
        }
        return fRet;
    }

    @Override
    public boolean editaFuncionario(Funcionario f) throws Exception {

        boolean saved = false;
        Connection con = null;

        try {

            con = FabricaConexao.getConexao();
            con.setAutoCommit(false);

            String sqlPessoa = "update Pessoas set  cpf = ? where idPessoas = ?";

            PreparedStatement pstmtPessoa = con.prepareStatement(sqlPessoa);

            pstmtPessoa.setString(1, f.getCpf());
            pstmtPessoa.setInt(2, f.getIdPessoa());

            pstmtPessoa.executeUpdate();

            String sqlFunc = "update Funcionarios set perfil = ? where Pessoas_idPessoas = ?";

            PreparedStatement pstmtFunc = con.prepareStatement(sqlFunc);

            pstmtFunc.setString(1, f.getPerfil());
            pstmtFunc.setInt(2, f.getIdPessoa());

            pstmtFunc.executeUpdate();

            ContatoDAO contatoDAO = new ContatoDAOImp();
            contatoDAO.editaContato(f, con);

            EnderecoDAO endDAO = new EnderecoDAOImp();
            endDAO.editaEndereco(f, con);

            LoginDAO loginDAO = new LoginDAOImp();
            loginDAO.editaLogin(f, con);
            
            con.commit();

            saved = true;

        } catch (SQLException e) {
            throw new Exception("Erro ao editar funcionário: " + e.getMessage());
        } finally {
            FabricaConexao.fechar(con);
        }
        return saved;
    }
}
